#ifndef DOMINION_H_INCLUDED
#define DOMINION_H_INCLUDED
#include "dominion.h"
#endif

#ifndef TIME_H_INCLUDED
#define TIME_H_INCLUDED
#include <time.h>
#endif


#include "randomutils.h"
#include <stdio.h>

/*
 * return the number of treasures in the crrent hand
 */
int num_treasures_hand(int player, struct gameState* G)
{
	int num_treasure = 0;

	int i;
	for(i = 0; i < G->handCount[player]; i++)
	{
		if(G->hand[player][i] >= copper && G->hand[player][i] <= gold)
		{
			num_treasure++;
		}
	}
	return num_treasure;
}

/*
 * returns a int* of how many treasures not in the hand
 * index:
 * 	0 = numcopper
 * 	1 = numsilver
 *	2 = numgold
 */
int num_treasures_not_hand(int player, struct gameState* G)
{
	// init a 0 set array
	int num_treasure = 0;

	int i;
	for(i = 0; i < G->deckCount[player]; i++)
	{
		if(G->deck[player][i] >= copper && G->deck[player][i] <= gold)
		{
			num_treasure++;
		}
	}

	for(i = 0; i < G->discardCount[player]; i++)
	{
		if(G->discard[player][i] >= copper && G->discard[player][i] <= gold)
		{
			num_treasure++;
		}
	}
	return num_treasure;
}

int testAdventure()
{
	// initialize the random game
	struct gameState* G = random_game_state();

	//decide which player we wish to have play
	int player = rand() % G->numPlayers;	

	// make sure we are in the right state for this player
	// to play
	setup_for_player(player, G);
	//randomize that player's cards
	random_deck(player, G);
	random_discard(player, G);
	random_hand(player, G);

	// determine where to put an adventure
	int adv_pos;
	if(G->handCount[player] == 0)
	{
		adv_pos = 0;
	}
	else
	{
		adv_pos = rand() % G->handCount[player];
	}
	G->hand[player][G->handCount[player]] = G->hand[player][adv_pos];
	G->handCount[player] = G->handCount[player] + 1;
	G->hand[player][adv_pos] = adventurer;

	// make sure we know how many treasure exists in all
	// but the hand
	int num_treasure_not_hand = num_treasures_not_hand(player, G);
	int num_treasure_in_hand = num_treasures_hand(player, G);

	// a fixture to know how many should be in the hand after 
	int num_treasure_in_hand_after = num_treasure_in_hand;
	
	// init expected post-op num actions and buys
	int num_actions = G->numActions - 1;
	int num_buys = G->numBuys;

	if(num_treasure_not_hand < 2)
	{
		num_treasure_in_hand_after += num_treasure_not_hand;
	}
	else
	{
		num_treasure_in_hand_after += 2;
	}

	// a fixture to know how many should be in not hand after
	int num_treasure_not_in_hand_after = num_treasure_not_hand - 2;
	if(num_treasure_not_in_hand_after < 0)
	{
		num_treasure_not_in_hand_after = 0;
	}


	// send G through the proven working instance
	playCard(adv_pos, 0, 0, 0, G);

	// check for correct treasure in hand
	if(num_treasure_in_hand_after != num_treasures_hand(player, G))
	{
		printf("Error: Expected %d treasures in hand, got %d\n",
				num_treasure_in_hand_after,
				num_treasures_hand);
		return 1;
	}

	// check for correct treasure in not hand
	if(num_treasure_not_in_hand_after != num_treasures_not_hand(player, G))
	{
		printf("Error: Expected %d treasures in deck and discard, got %d\n",
				num_treasure_not_in_hand_after,
				num_treasures_not_hand(player, G));
		return 1;
	}
	
	// check for correct numActions
	if(num_actions != G->numActions)
	{
		printf("Error: Expected %d actions left, got %d\n",
				num_actions,
				G->numActions);
		return 1;
	}

	// check for correct num_buys
	if(num_buys != G->numBuys)
	{
		printf("Error: Expected %d buys left, got %d\n",
				num_buys,
				G->numBuys);
		return 1;
	}

	printf("Pass\n");
	return 0;
}

int main()
{
	srand(time(NULL));
	int test_value = 0;
	int i;
	for(i = 0; i < 15000; i++)
	{
		if(testAdventure() == 1)
		{
			test_value = 1;
		}
	}
	if(test_value == 1)
	{
		printf("Test Summary: FAIL");
	}
	else
	{
		printf("Test Summary: PASS");
	}
	return 0;
}
